<?

/**
 * Read config file: spotlight.xml end save to session.  
 * 
 * @version since begin
 * @author asmhack
 * @license GPL
 * @copyright Serhiy Zaporozhets'
 */
class ConfigReader {
	
	private $pack;
	
	private $base;
	
	public static function getInstance() {
		if (! Session::isExist ( 'confMap', false ))
			new ConfigReader ( );
		return Session::getSystemValue ( 'confMap' );
	}
	
	public function __construct() {
		// if is dev mode then read spotlight.xml any time. else read it at only first start.  )))
		if (Session::getSystemValue ( 'dev', false ) == true) {
		} elseif (Session::isExist ( 'confMap', false ))
			return;
		
		$this->base = 'SpotLight/configs/';
		
		$xml = @simplexml_load_file ( $this->base . 'spotlight.xml' );
		if ($xml != null) {
			
			$this->pack = new PackageColl ( );
			
			if (isset ( $xml->template )) {
				$this->pack->setTemplate ( strval ( $xml->template ['name'] ) );
			} else
				throw new ConfigException ( 'Can\'t find <b>template</b> mapping "SpotLight/configs/<b>spotlight.xml</b>".' );
				
			# <dispatcher ...> parse::
			if (count ( $xml->dispatcher ) < 1)
				throw new ConfigException ( 'Can\'t find anyone <b>dispatcher</b> in file "SpotLight/configs/<b>spotlight.xml</b>".' );
			
			foreach ( $xml->dispatcher as $dispatch ) {
				$reqDisp = new DispatcherColl ( );
				$reqDisp->setClass ( strval ( $dispatch ['class'] ) );
				$reqDisp->setType ( isset ( $dispatch ['type'] ) ? strval ( $dispatch ['type'] ) : 'request' );
				$this->pack->addDispatcher ( isset ( $dispatch ['type'] ) ? strval ( $dispatch ['type'] ) : 'request', $reqDisp );
			}
			
			foreach ( $xml->flow as $flow ) {
				$this->readFlowFile ( strval ( $flow ['file'] ), $this->pack );
			}
			
			# <action ...> parse::
			$this->actionParse ( $xml->action, $this->pack );
			
			# <interceptor .../> parse::
			$this->interceptorsParse ( $xml->interceptor, $this->pack );
			
			# <excludes .../> parse::
			$this->excludesParse ( $xml->excludes, $this->pack );
			
			# <tags .../> parse::
			$this->tagsParse ( $xml->tags, $this->pack );
			
			Session::putSystemValue ( 'confMap', $this->pack, true );
			//Session::put( 'cm',$this->pack,true );
		

		} else
			throw new ConfigException ( 'Can\'t find "SpotLight/configs/<b>spotlight.xml</b>" file. Please check path.' );
		
	//die ( $this->pack );
	}
	
	public function readFlowFile($flowFileName, &$pack) {
		$xml = @simplexml_load_file ( $this->base . $flowFileName );
		if ($xml != null) {
			$flow = new FlowColl ( );
			$flow->setName ( strval ( $xml ['name'] ) );
			$flow->setFile ( $flowFileName );
			# <action ...> parse::
			$this->actionParse ( $xml->action, $flow );
			
			# <interceptor .../> parse::
			$this->interceptorsParse ( $xml->interceptor, $flow );
			
			# <excludes .../> parse::
			$this->excludesParse ( $xml->excludes, $flow );
			
			$pack->addFlow ( strval ( $xml ['name'] ), $flow );
		} else
			throw new ConfigException ( 'Can\'t find Flow config "<b>' . ($this->base . $flowFileName) . '</b>" file. Please check path.' );
	}
	
	private function interceptorsParse($interceptorsArray, &$pack) {
		foreach ( $interceptorsArray as $interceptor ) {
			if (isset ( $interceptor ['class'] )) {
				$interceptorColl = new InterceptorColl ( );
				if (! isset ( $interceptor ['class'] ))
					throw new ConfigException ( 'Can\'t find <b>class</b> attribute for interceptor in file "SpotLight/configs/<b>spotlight.xml</b>".' );
				$interceptorColl->setClass ( strval ( $interceptor ['class'] ) );
				
				if (! isset ( $interceptor ['file'] ))
					throw new ConfigException ( 'Can\'t find <b>file</b> attribute for <b>' . $interceptor ['class'] . '</b> interceptor in file "SpotLight/configs/<b>spotlight.xml</b>".' );
				$interceptorColl->setFile ( strval ( $interceptor ['file'] ) );
				$interceptorColl->setType ( isset ( $interceptor ['type'] ) ? strval ( $interceptor ['type'] ) : 'before' ); // set defult filter type:: "before"
				$interceptorColl->setUrl ( isset ( $interceptor ['url'] ) ? '/' . (strval ( $interceptor ['url'] )) . '/' : '/(.*)/' ); // instead   '/*/'
				$pack->addInterceptor ( $interceptorColl );
			} else
				die ( 'Ivalid XML config<br/>No filter class name defined.' );
		}
	}
	
	private function actionParse($actionsArray, &$pack) {
		foreach ( $actionsArray as $action ) {
			if (isset ( $action ['name'] )) {
				
				$act = new ActionColl ( );
				$act->setName ( strval ( $action ['name'] ) );
				$act->setClass ( isset ( $action ['class'] ) ? strval ( $action ['class'] ) : null );
				if (isset ( $action ['class'] ) && ! isset ( $action ['file'] ))
					throw new ConfigException ( 'Can\'t find <b>file</b> attribute for action in file "SpotLight/configs/<b>spotlight.xml</b>".' );
				if (isset ( $action ['file'] ) && ! isset ( $action ['class'] ))
					throw new ConfigException ( 'Can\'t find <b>class</b> attribute for action in file "SpotLight/configs/<b>spotlight.xml</b>".' );
				$act->setFile ( isset ( $action ['file'] ) ? strval ( $action ['file'] ) : null );
				$act->setMethod ( $action ['method'] ? strval ( $action ['method'] ) : 'execute' );
				
				# <result ...> parse::
				$this->resultParse ( $action->result, $act );
				
				# <interceptor .../> parse::
				$this->interceptorsParse ( $action->interceptor, $act );
				$pack->addAction ( $act );
			} else
				throw new ConfigException ( 'Can\'t find <b>name</b> attribute for action in file "SpotLight/configs/<b>spotlight.xml</b>".' );
		}
	}
	
	private function excludesParse($excludesArray, &$pack) {
		foreach ( $excludesArray as $exclude ) {
			foreach ( $exclude->name as $exName ) {
				$pack->addExclude ( strval ( $exName ) );
			}
		}
	}
	
	private function tagsParse($tagsArray, &$pack) {
		foreach ( $tagsArray as $tag ) {
			foreach ( $tag->tld as $fileName ) {
				list ( $prefix, $tagLibColl ) = $this->readTagLibFile ( $fileName );
				$pack->addTagLib ( $prefix, $tagLibColl );
			}
		}
	}
	
	public function readTagLibFile($fileName) {
		$xml = @simplexml_load_file ( $this->base . $fileName );
		if ($xml != null) {
			$tagLibColl = new TagLibColl ( );
			$tagLibColl->setPrefix ( strval ( $xml ['prefix'] ) );
			# <action ...> parse::
			foreach ( $xml->tag as $tag )
				$tagLibColl->addTag ( strval ( $tag->class ), strval ( $tag->file ) );
			
			return array (strval ( $xml ['prefix'] ), $tagLibColl );
		} else
			throw new ConfigException ( 'Can\'t find tag lib definition file "<b>' . ($this->base . $fileName) . '</b>" file. Please check path.' );
	}
	
	private function resultParse($resultsArray, &$pack) {
		foreach ( $resultsArray as $result ) {
			$res = new ResultColl ( );
			$res->setAction ( isset ( $result ) ? strval ( $result ) : null );
			$res->setName ( isset ( $result ['name'] ) ? strval ( $result ['name'] ) : null );
			$res->setType ( isset ( $result ['type'] ) ? strval ( $result ['type'] ) : 'ajax' );
			$pack->addResult ( $res );
		}
	}

}
?>